﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Linq;

namespace TEST
{
	public static class Serialize
	{
		public static string JsonSerialize(this object toSer)
		{
			System.Web.Script.Serialization.JavaScriptSerializer ser = new System.Web.Script.Serialization.JavaScriptSerializer();
			return ser.Serialize(toSer);
		}

		public static T JsonDeSerialize<T>(this string toDeSer)
		{
			System.Web.Script.Serialization.JavaScriptSerializer ser = new System.Web.Script.Serialization.JavaScriptSerializer();
			return ser.Deserialize<T>(toDeSer);
		}

		public static string XmlSerialize(this object toSer, bool removeAllAttributes = false,
			bool removeXsd = false,
			bool removeXsi = false,
			string[] removeNode = null)
		{
			System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(toSer.GetType());
			string xml = string.Empty;
			using (MemoryStream stream = new MemoryStream(100))
			{
				ser.Serialize(stream, toSer);
				stream.Position = 0;
				StreamReader reader = new StreamReader(stream, Encoding.UTF8);
				xml = reader.ReadToEnd();

				reader.Close();
			}
			var xe = XElement.Parse(xml);
			if (removeAllAttributes)
			{
				xe.RemoveAttributes();
			}
			RemoveXsXXX(removeXsd, removeXsi, xe);

			if (removeNode != null && removeNode.Length > 0)
			{
				List<XElement> removeList = new List<XElement>();
				foreach (var item in xe.Elements())
				{
					if (removeNode.Contains(item.Name.LocalName))
					{
						removeList.Add(item);
					}
				}
				foreach (var item in removeList)
				{
					item.Remove();
				}
			}
			return "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + System.Environment.NewLine + xe.ToString(); ;
		}
		/// <summary>
		/// 移除xsd和xsi
		/// </summary>
		/// <param name="removeXsd"></param>
		/// <param name="removeXsi"></param>
		/// <param name="xe"></param>
		private static void RemoveXsXXX(bool removeXsd, bool removeXsi, XElement xe)
		{
			List<XAttribute> rList = new List<XAttribute>();
			foreach (var item in xe.Attributes())
			{
				if (removeXsd && item.Name.LocalName == "xsd")
				{
					rList.Add(item);
				}
				if (removeXsi && item.Name.LocalName == "xsi")
				{
					rList.Add(item);
				}
			}
			foreach (var item in rList)
			{
				item.Remove();
			}
		}
		/// <summary>
		/// xml反序列化
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="s"></param>
		/// <returns></returns>
		public static T XmlDeserialize<T>(this string s)
		{
			XmlDocument xdoc = new XmlDocument();
			xdoc.LoadXml(s);
			XmlNodeReader reader = new XmlNodeReader(xdoc.DocumentElement);
			XmlSerializer ser = new XmlSerializer(typeof(T));
			object obj = ser.Deserialize(reader);
			return (T)obj;
		}


		public static void Test()
		{

			Person test = new Person()
			{
				age = 24,
				sex = 1,
				name = "cgyqu",
				CDataContent = "测试",
			};
			//string s = test.JsonSerialize();
			//Console.WriteLine(s);
			//Person t = s.JsonDeSerialize<Person>();
			//Console.WriteLine(t.sex);
			string s1 = test.XmlSerialize(removeXsd: true, removeXsi: true, removeNode: new string[] { "sex", "Contents" });
			Console.WriteLine(s1);
			Person t1 = s1.XmlDeserialize<Person>();
			Console.WriteLine(t1.name);
			Console.WriteLine(t1.CDataContent);
		}
	}
	[XmlRoot("person")]
	[Serializable]
	public class Person
	{
		public int age { get; set; }

		public string name { get; set; }

		public int sex { get; set; }

		[XmlIgnore]
		public string CDataContent { get; set; }

		[XmlElement("Content")]
		public XmlNode Nodes
		{
			get
			{
				var dom = new XmlDocument();
				return dom.CreateCDataSection(CDataContent);
			}
			set
			{
				if (value != null)
				{
					CDataContent = value.Value;
				}
			}
		}
	}
}
